• 返回首页

      Java学习笔记——By Bug

      前言

      参考资料: 【Java入门基础视频教程,java零基础自学就选黑马程序员Java入门教程(含Java项目和Java真题)】 https://www.bilibili.com/video/BV1Cv411372m/?share_source=copy_web&vd_source=ea0cf64e8dac6f0193a7e28187a0fccb

      Java下载:Java Downloads | Oracle

      说明: 本笔记为本人学习过程中随手写的笔记,为复习使用,笔记中可能存在遗漏或错误,具体请以官方文档和权威书籍为准!谢谢! 笔记中的一些图片等元素因路径配置问题,可能会发生丢失。 笔记中展示的构造器和方法等的知识点仅为部分内容,完整内容请查阅官方开发文档内容!

      👇JavaSE👇

      Java介绍

      简介

      什么是 Java 技术,为什么需要它?

      Java 是 Sun Microsystems 于 1995 年首次发布的一种编程语言和计算平台。它已经从不起眼的开始发展到为当今数字世界的很大一部分提供动力,通过提供可靠的平台来构建许多服务和应用程序。为未来设计的创新产品和数字服务也继续依赖于 Java。

      虽然大多数现代 Java 应用程序将 Java 运行时和应用程序结合在一起,但仍有许多应用程序甚至某些网站无法运行,除非您安装了桌面 Java。Java.com,这个网站,是为那些可能仍然需要 Java 的桌面应用程序(特别是面向 Java 8 的应用程序)的消费者准备的。

       

      搭建开发环境

      Java产品叫JDK(Java开发者工具包),必须安装JDK才能使用Java

      1. 下载:Java Downloads | Oracle image-20240426192608086

      2. 安装:运行安装包程序,安装软件 注意:安装目录尽量避免包含中文和空格 验证Java程序是否安装完成方法:

        image-20240426215548355

       

      第一个Java程序

      Java程序开发步骤:编写代码——编译代码——运行代码

      image-20240426220652510

      1. 用记事本创建一个helloworld.java文件(文件名建议使用英文) image-20240426220754416

      2. 编写java代码

        文件名要于类名一致

      3. 编译代码

        • 打开命令行窗口,运行javac helloworld.java

        • 会生成一个helloworld.class后缀的文件 image-20240426221826990

      4. 运行代码 命令行窗口运行:java helloworld image-20240426221927088

       

      JDK组成和跨平台原理

      JDK组成

      跨平台原来

       

      IntelliJ IDEA开发工具

      概述 IntelliJ IDEA(简称 IDEA)是一款由 JetBrains 公司开发的强大且广受欢迎的集成开发环境(IDE),主要用于Java开发,但也支持其他编程语言和技术栈的开发。作为一款功能丰富、高效的IDE,IntelliJ IDEA 在软件开发领域中广泛用于开发各种类型的应用程序,从桌面应用到Web应用、移动应用、大数据和云计算应用等等。

      1. 下载地址:Download IntelliJ IDEA – The Leading Java and Kotlin IDE (jetbrains.com) 下载社区版即可 image-20240427225359609

      2. 安装 运行idea安装程序

      3. 汉化(非必须) 在插件中找到chinese汉化包,安装后冲的idea即可

       

      新建项目

      建议使用空项目image-20240428110746656

      小技巧:快速创建main函数方法

      1. 输入main,回车

      2. 输入psvm,回车

      示例代码

       

      IDEA配置

      快捷键

      快捷键功能
      main/psvm/sout快速输入相关代码
      ctrl+d复制当前行代码到下一行
      ctrl+y删除所在行
      ctrl+L格式化代码
      alt+shift+↑/↓上下移动代码
      ctrl+/ ctrl+shift+/注释代码

       

      入门内容

      注释

      快捷键作用
      ctrl+/单行注释
      ctrl+shift+/多行注释

       

      字面量

      在Java中,字面量(literal)指人类可以阅读的固定值的表示。例如,数100是字面量。字面量也常常称为常量(constant)

      Java的字面量可以是任意基本数据类型。每种字面量的表示取决于类型。如前所述,字符常量由单引号包括。例如,'a'和'%'都是字符常量。

      类型字面量备注
      整数199,-199 
      小数-5.1,5.1 
      字符'a'''(单引号),有且只有一个字符
      字符串"aaaaaa"""(双引号),可以有一个字符,也可以多个字符,也可以不写
      null 
      布尔值true,false 

       

      变量

      变量定义格式: 数据类型 变量名称=数据;

      注意:

      1. 变量要先声明再使用

      2. 变量是什么类型,对应的数据就要是什么类型,否则会报错

      3. 定义多个变量,变量名不能相同

      4. (局部)变量再当前作用域{}内有效,超出后无效

      5. 变量在声明时可以不赋值,但在使用时必须要复制,否则将会报错

       

      关键字与标识符

      关键字 Java 中的关键字是指具有特定含义的单词或符号,这些关键字在 Java 编程中有着重要的作用。Java 关键字分为基本关键字、访问修饰符、类和接口关键字等。

      标识符

      Java 中的标识符是指用于命名变量、常量、方法、类、接口等的名称。Java 的标识符需要符合一定的规则,具体如下:

      Java 中常用的标识符包括变量名、常量名、方法名、类名、接口名等。

       

      ===面向对象基础篇===

      数据类型

      基本数据类型

      类型关键字内存占用数据范围
      整型byte1-128-127
       short2-32768-32767
       int(default)4-2147483648-2147483647(10位)
       long8-2^63 ~ 2^63 - 1 (19位)
      浮点型float41.401298E-45---3.402825E+38
       double(default)84.9000000E-45---1.797693E+308
      布尔型boolean1true,false
      字符型char20-65535

      引用数据类型

      String——字符串数据类型

       

      数据类型转换

      自动类型转换

       

      表达式的自动类型转换

       

      强制类型转换

      大范围的变量赋值给小范围的时,需要强制类型转换

      注意:

       

      运算符

      算数运算符

      符号作用
      +
      -
      *
      /除(两个整数相除只保留整数)
      %取余

      可以使用 + 做连接符

       

      自增自减运算符

      符号作用
      ++自增,对自身变量+1
      --自减,对自身变量-1

       

      赋值运算符

      符号作用
      =赋值
      +=加后赋值
      -=减后赋值
      *=乘后赋值
      /=除后赋值
      %=取余后赋值

       

      关系运算符

      符号作用
      >大于
      >=大于等于
      <小于
      <=小于等于
      ==等于
      !=不等

       

      逻辑运算符

      符号作用
      &逻辑与
      |逻辑或
      !逻辑非
      ^逻辑异或
      符号作用
      &&左边为false右边不执行
      ||左边为true右边不执行

       

      三元运算符

      格式:表达式?值1:值2;

      表达式为true时,返回值1,false时,返回值2

       

      运算符优先级

      优先级类型符号
      1括号()、[ ]、.
      2非、正,负号!、+(正)、-(负)
      3自增,自减++、--
      4乘,除,取余*、/、%
      5加,减+、-
      6移位运算<<、>>、>>>
      7大小关系<、<=、>、>=
      8相等关系==、!=
      9按位与&
      10按位异或(在java中,这不是幂次方的符号)^
      11按位或|
      12逻辑与(短路与)&&
      13逻辑或(短路或)||
      14条件运算(三目运算)? :
      15赋值运算=、+=、-=、*=、/=、%=
      16位赋值运算&=、|=、^=、~=、<<=、>>=、>>>=

       

      JavaAPI

      API文档下载(以java21为例):Java Development Kit 21 Documentation (oracle.com)

      image-20240508211944691

       

      API使用:

      1. 导入包

      2. 使用包中的程序

      例如使用scanner

       

      流程控制

      分支结构

      if

      if分支结构的三种形式

       

      switch

      语法:

      注意:

      1. case的值只能是字面量,不能为变量,case的值不能重复

      2. 语句结束后要使用break,否则会出现穿透现象

      3. switch表达式类型只能是byte,short,int,char,enum,string不支持double,float,long

       

      循环结构

      for循环

      案例

       

      while循环

       

      do-while循环

      循环注意事项

      while循环和do-while循环的区别:

      死循环写法

      示例

       

      跳转关键字

      break---终止当前循环 只能用于所在循环,或结束所在switch分支的执行

      continue---跳过本次循环 只能用于循环中

       

      案例:生成随机数

       

      数组

      数组是一个容器,用来存储一批同类型的数据

      静态数组初始化

      初始化

       

      静态数组访问

      语法:数字名[索引号]

      数组的最大索引长度:数组长度-1

       

      数组遍历

       

      动态初始化数组

      数组的动态初始化——再定义数组时先不存入具体的元素值,只确定数组存储的数据类型和长度

      动态初始化格式:

       

      案例:计算评分

      案例:随机排名

       

      方法

      方法是一种语法结构,它可以把一段代码封装成一个功能

      方法定义

      语法:

      方法定义时要注意: 1.方法是否需要接收处理数据 2.方法是否需要返回数据

      注意事项

      方法使用的常见问题

       

      参数传递机制

      java参数传递机制:值传递 指的是在传输实参给方法的形参时,传输的时实参变量中储存的值的副本

       

      案例:打印int数组内容

       

      方法重载

      在一个类中,出现多个重名方法,但是,它们的形参列表是不同的,那么这些方法就称为方法重载

       

      return关键字

      return关键字可以用于无返回值的方法中 作用:立即跳出并结束当前方法

       

      案例篇

      买飞机票

      需求 用户购买机票时,机票原价会按淡季,旺季,头等舱还是经济舱的情况进行相应的优惠方案,优惠方案如下:5-10月为旺季,头等舱9折,经济舱8.5折;11月-次年4月为淡季,头等舱7折,经济舱6.5折,请开发程序计算出用户当前机票的优惠价格

       

      验证码

      需求 开发一个程序,可以生成指定位数的验证码,每位都可以输数字或大小写字母

       

      评委打分

      需求 在一个比赛中,有多名评委对选手进行打分,分数在0-100之间的整数,去掉打分中的最高分和最低分,对剩下的分数求平均,作为选手的最终得分

       

      数字加密

      需求 某个系统的密码是一个四位数,如:1987,为了安全,需要对密码进行加密后在进行传输,加密规则:对密码中的每位数都加5,再对10求余数,得到一串加密后的新数

       

      数组拷贝

      需求 现有一个数组a,拷贝一份一模一样的数组b

       

      抢红包

      需求 在一个活动中,有五个红包,金额为:9,199,520,666,999请模拟抽奖,每个红包只能抽一次,顺序随机

       

      找素数

      需求 输入开始和结束的两个数,判断之间有多少素数

       

      打印乘法表

      需求 打印99乘法表

       

      面向对象

      入门示例

      image-20240602222309822

      注意事项

      1. 类名建议首字母大写,使用驼峰命名法。

      2. 类中定义的变量也成为成员变量(对象的属性),类中定义的方法也成为成员方法(对象的行为)。

      3. 成员对象本身存在默认值,在定义时一般情况下不对其进行赋值。

      4. 一个代码文件中,可以有多个class,但只能有一个用public修饰,且public修饰的类名必须和文件名相同。

      5. 对象和对象之间的数据不会相互影响,但多个变量指向同一个对象就会相互影响

      6. 如果某个对象没有一个变量引用它,则该对象就无法被操作,该对象被称为垃圾对象

       

      this关键字

      this是什么? this是一个变量,可以在方法中使用,来拿到当前对象

      应用场景 this主要用来解决变量名称冲突问题

      this可以获取当前对象的地址

      构造器

      构造器是一种特殊的方法,构造器名字要和class类的类名相同,且不能声明返回值类型

      若不写构造器,Java会默认生成一个无参数构造器 一旦定义了有参构造器,Java就不会再默认提供无参数构造器

       

      封装

      什么是封装? 封装就是用类设计对象处理某一个事物的数据时,应该把要处理的数据以及处理的方法设计到一个对象中去

      封装的设计规范 合理隐藏,合理暴露

      控制对象的公开和隐藏

       

      实体JavaBean

      实体类:一种特殊形式的类

      1. 这个类中的成员变量都要是私有的,并且要对外提供get,set方法

      2. 这个类中必须有一个公共无参的构造器

      应用场景

      实体类只负责数据的存取,而对数据的处理由其他类来完成,实现数据和数据业务处理分离

       

      综合案例——模仿电影信息系统

       

      成员变量和局部变量

      两种变量的区别

      区别/类型成员变量局部变量
      在类中位置不同在类中,方法外常见于方法中
      初始值不同有默认值,不需要初始化没有默认值,使用前必须赋值
      内存位置不同存在于堆内存存在于栈内存
      作用域不同整个对象在所属的大括号中
      生命周期不同与对象一起产生或销毁方法调用产生,方法结束销毁

       

      总结

      定义类的格式

      注意事项

      1. 类名首字母大写,有意义,使用驼峰命名法,不能使用关键字,合法的标识符

      2. 一个Java文件中可以定义多个类,但只能有一个是public修饰的,且public修饰的类必须和Java文件名相同

       

      面向对象高级语法

      JavaAPI

      API:应用程序编程接口

      JavaAPI文档:Java SE 文档 — API 和文档 | Oracle 中国

      在自己程序中调用其他包的注意事项

       

      String

      创建字符串的方式

      1. Java程序中所有的字符串文字都是此类对象

      2. 调用构造器初始化字符串对象 下面是常用的构造器

        构造器说明
        public String()创建一个空白的字符串对象,不含有任何内容
        public String(String tex)根据传入的字符串,来创建字符串对象
        public String(char[] chars)根据字符数组的内容,来创建字符串对象
        public String(byte[] bytes)根据字节数组的内容,来创建字符串对象

         

      String常用方法
      方法名返回值说明
      length()int获取字符串的长度
      charAt(int index)char获取某个索引位置处的字符返回
      toCharArray():char[]将当前字符串转换成字符数组返回
      equals(Object anObject)boolean判断当前字符串与另一个字符串内容是否一样,返回true或false
      equalsIgnoreCase(String anotherString)boolean判断当前字符串与另一个字符串内容是否一样,返回true或false(忽略大小写)
      substring(int beginIndex,int endIndex)String根据开始和结束索引进行截取字符串(含开始不含结束),得到新的字符串
      substring(int beginIndex)String从开始索引进行截取字符串至结尾,得到新的字符串
      replace (CharSequence target,CharSequence replacement)String使用新值替换字符串中的旧值,得到新的字符串
      contains(CharSequence s)boolean判断字符串中是否包含某个字符
      startWith(String prefix)boolean判断字符串是否以某个字符串内容开头,返回true或false
      split(String regex)String[]把字符串按照某个字样进行分割,并返回字符串数组

       

      String注意事项
      1. String对象的内容是不可改变的,被称为不可改变字符串对象。

      2. 只要是以 ”双引号“ 包裹的字符串对象,都会被存储到字符串常量池,且相同的字符串内容只会存储一份

      3. 通过new方式创建的字符串对象,每new一次都会产生一个新的对象放在堆内存中

       

      String应用案例
      用户登录

      用户输入账号和密码登录,登陆成功后欢迎,停止程序,失败次数最多为3次,超出次数登录失败,程序停止

      随机验证码(String版)

       

      ArrayList

      ArrayList是集合,集合是一种容器,类似于数组。 数组的长度是固定的,集合的大小是可变的。功能更加强大,适合做元素个数不确定,存在增删改查操作的场景

      集合都是支持泛型的

       

      创建ArrayList对象

       

      ArrayList的操作

       

      ArrayList构造器
      构造器描述
      ArrayList()构造一个初始容量为10的空列表(常用)
      ArrayList(int intialcapacity)构造具有初始容量的空列表
      ArrayList(Collection<? extends E> c)按照集合的迭代器返回的顺序,构造一个包含指定元素的列表

       

      ArrayList常用方法
      方法名返回值类型说明
      add(E e)boolean将指定的元素添加到集合的末尾
      add(int index,E element)void在集合的指定(index)位置插入指定元素
      get(int index)E返回指定索引处的元素
      size()int返回集合中的元素个数
      remove(int index)E删除指定索引处的元素,返回被删除的元素
      remove(Object 0)boolean删除指定的元素,返回删除是否成功
      set(int index,E element)E修改指定索引处的元素,返回被修改的元素

       

      ArrayList应用案例

      购物车 需求:

      1. 使用ArrayList集合表示购物车,存储商品名

      2. 遍历集合中的数据,包含枸杞的删除

      3. 输出集合内容,检查是否删除成功

       

      模拟外卖系统 需求:

      方法一:集合嵌套

       

      方法二:使用成员变量存储数据

       

      项目案例:模拟ATM系统

      项目分析

       

      项目代码展示

       

      ===面向对象高级篇===

      static

      static:静态,可以修饰成员变量和成员方法

       

      static修饰成员变量

      成员变量按照有无static修饰分为:

      static修饰成员变量应用场景

      在开发中,如果某一份数据只需要一份,且希望被共享,则该数据可以被定义为类变量。

      例如:用户管理系统中,我们可以定义一个静态的number,来统计系统中创建的用户总数。

       

      static修饰成员方法

      成员方法的分类:

      类方法的访问方法与类变量的访问方法相同。

      static修饰成员方法应用场景

      类方法最常见的应用场景是作为工具类的。 工具类是个开发人员使用的。 优点:提高了代码的复用性,调用方便,提高了开发效率。

      例如:随机验证码生成程序,可以封装成一个类方法,当程序中需要生成验证码时,就进行调用。

       

      static的注意事项

       

      static的应用:代码块

      什么是代码块? 代码块是类的五大成分之一(成员变量,构造器,方法,代码块,类)

      代码块分为两种

      static的应用:单例设计模式

      什么是设计模式 一个问题通常由n种解法,其中有一种最优解,这个最优解被总结出来被称为设计模式 sh耳机模式有二十多种,对应开发中会遇到的20多个问题

       

      单例设计模式

      作用:确保一个类只有一个对象

      写法:

       

      继承

      继承的使用

      什么是继承? 让一个类和另一个类建立起父子关系 Java中提供了关键字extends建立两个类之间的继承关系

      语法

      继承的特点 子类能继承父类的非私有成员(成员变量,成员方法),私有的类变量是无法被继承的

      使用继承的优点 减少重复代码的编写。提高了代码的复用性

      案例:继承

      需求:有老师和学生类,两个类有公共的姓名性别年龄,老师有职称信息,学生有班级信息

       

      继承的注意事项

      子类构造器的特点

       

      多态

      什么是多态

      多态是在继承/实现情况下的一种现象,表现为:对象多态,行为多态。

      多态代码表现


       

      多态的前提

      有继承/实现关系;存在父类引用子类对象;存在方法重写。

      多态是对象、行为的多态,Java的属性(成员变量)无多态

       

      多态的好处

      多态的问题

      多态下,不能调用子类独有的功能

       

      多态下的类型转换

      类型转换 自动类型转换:父类 变量名= new 子类()

      强制类型转换:子类 变量名=(子类)父类变量

      强转注意事项

      存在继承/实现关系,就可以在编译阶段进行强制类型转换,编译阶段不会报错。 运行时,如果发现对象的真是类型与强制转换后的类型不同,就会报类型转换异常的错误。

      final

      认识final

       

      常量

      使用常量的好处

      常量的执行原理

       

      抽象类

      认识抽象类

      抽象方法的特点和注意事项

       

      抽象类的优点

      抽象类的应用场景

      模板方法设计模式——解决方法中存在重复代码问题

       

      接口

      接口概述

      在Java中提供了一个关键字interface ,用这个关键字可以定义一个特殊的结构:接口

      在新建类时,选择接口 image-20240727113759698

      接口语法

      接口是不能创建对象的;接口是用来被类实现的(implements),实现接口的类被称为实现类。

      一个类可以实现多个接口,实现类实现多个接口时,必须 重写完全部接口的全部抽象方法,否则这个类也需要定义成抽象类

       

      接口的优点

       

       

      综合案例

      学生信息系统:两套方案如下

      1. 能打印所有学生信息,能打印所有学生的平均分。

      2. 能打印所有学生信息(男女生人数),能打印所有学生的平均分(去除最高分和最低分)。

      要求:系统可以灵活的切换这两套输出方案

      其他细节

       

      内部类

       

      枚举

      认识枚举

      枚举是一种特殊的类

      枚举类的语法格式:

      枚举类的特点

       

      枚举的应用场景 用来表示一组参数,作为参数进行传输

       

      泛型

      泛型类

      定义泛型类的语法

       

      泛型接口

      定义的语法

      场景:系统需要处理学生和老师的数据,提供两个功能:保存对象数据,根据名称查询数据

       

      泛型方法

      泛型方法定义语法

      泛型的上下限

       

      泛型注意事项

       

      常用API

      object类

      object类是类层结构的根,每个类都有object类作为超类。

      方法名返回值类型说明
      toString()String返回对象字符串表示形式
      equals()boolean判断两个对象是否相等
      clone()object克隆对象

      浅克隆

      拷贝出的新对象和原来对象中的数据一模一样(引用类型只拷贝其地址)

      深克隆

       

      objects

      objects类是一个工具类,其中提供了很多操作对象的静态方法。

      方法名返回值说明
      equals()boolean先做非空判断,再比较两个对象
      inNull()boolean判断对象是否为非空,为空返回true,反之false
      nonNull()boolean判断对象是否不为空,不为空返回true,反之false

       

      包装类

      包装类就是把基本类型的数据包装成对象

      基本数据类型包装类(引用数据类型)
      byteByte
      shortShort
      intInteager
      longLong
      charCharacter
      floatFloat
      doubleDouble
      booleanBoolean

      注意:Integer()已过时,可以使用下面的语法,将int包装成对象

      自动装箱机制:自动把基本类型的数据转换成对象

      自动拆箱机制:自动把包装类型转换成基本数据类型

      1. 把基本数据类型转成字符串

      2. 把字符串转换成基本数据类型

         

      StringBuilder

      StringBuilder代表可变字符串对象,相当于一个容器,它里面装的字符串是可以改变的,就是用来操作字符串的。

      StringBuilder相较于String的好处:更适合做字符串修改操作,效率更高,代码更加简洁。

      构造器说明
      StringBuilder()创建一个空白的可变字符串对象,不包含内容
      StringBuilder()创建一个指定字符串内容的可变字符串对象
      方法名称返回值类型说明
      append(任意类型)StringBuilder添加数据并返回StringBuilder对象本身
      reverse()StringBuilder将对象的内容反转
      length()int返回对象内容的长度
      toString()String把StringBuilder转换为String

      StringBuilder是支持链式编程的

      StringBuffer

      StringBuffer和StringBuilder的用法一模一样 但StringBuffer是线程安全的,StringBuilder是线程不安全的。

       

      StringJoiner

      和StringBuilder一样,也是用来操作字符串的,也可以看作一个容器,创建之后里面的内容是可变的。

      StringJoiner不仅提高字符串的操作效率,并且在有些场景下使用它操作字符串,代码会更加简洁

      构造器说明
      StringJoiner(间隔符号)创建一个StringJoiner对象,指定拼接时的间隔符号。
      StringJoiner(间隔符号,开始符号,结束符号)创建一个StringJoiner对象,指定拼接时的间隔符号,开始符号和结束符号。
      方法名返回值类型说明
      add()StringJoiner添加数据,返回对象本身
      length()int返回长度(字符出现的个数)
      toString()String返回一个字符串

      Math

      Math代表数学,是一个工具类,里面提供的都是对数据进行操作的一些静态方法。

      Math类常用的方法

      方法名返回值类型说明
      abs(int a)int获取参数绝对值
      ceil( double a)double向上取整
      floor(double a)double向下取整
      round(float a)int四舍五入
      max(int a,int b)/minint获取两个数的最大值/最小值
      pow(double a,double b)double返回a的b次幂
      random()double返回值为double的随机值,范围(0.0-1.0)

       

      System

      System代表程序所在的系统,是一个工具类

      System类常用方法

      方法名返回值类型说明
      exit(int status)该参数作为状态码0作为人为关闭,非零代表异常关闭void终止当前运行的虚拟机
      currentTimeMills()long返回当前系统的时间(毫秒)

       

      Runtime

      代表程序所在的运行环境。 它是一个单例类。只能提供一个对象。

      Runtime常用方法

      方法名返回值类型说明
      getRuntime()Runtime返回与当前Java应用程序关联的运行时对象
      exit(int status)void终止当前运行的虚拟机
      availableProcessors()int返回Java虚拟机可用的处理器数
      totalMemory()long返回Java虚拟机中的内存总量
      freeMemory()long返回Java虚拟机中可用内存
      exec(String command)Process启动某个程序,并返回代表该程序的对象

       

      (⭐)BigDecimal

      用于解决浮点型运算时,出现结果失真的问题

      BigDecimal常用构造器

      构造器说明
      BigDecimal(double a1) 不推荐将double转换为BigDecimal
      BigDecimal(string a1)将string转换成BigDecimal
      方法名返回值类型说明
      valueOf(double a1)BigDecimal将double转换成BigDecimal
      add(BigDecimal b)BigDecimal加法
      subtract(BigDecimal b)BigDecimal减法
      multiply(BigDecimal b)BigDecimal乘法
      divide(BigDecimal b)BigDecimal除法
      divide(另一个BigDecimal对象,精确即为,舍入模式)BigDecimal除法,可以控制精确到小数几位
      doubleValue()BigDecimal将BigDecimal转换成doule

       

      时间类

      传统时间(JDK8以前)

      这些API很多都已经过时了,不推荐使用!推荐使用JDK8以后新增的时间API

      新时间API(JDK8及以后)

      推荐使用新的时间API创建事件对象!

      这些方式创建出来的对象都是不可变对象,数据修改后会返回一组新的数据,不会修改原来的数据。 这样可以保留原来的日期对象。

      LocalDate、LocalTime、LocalDateTime

      LocalDate:本地日期(年、月、日、星期) LocalTime:本地时间(时,分,秒,纳秒) LocalDateTime:代表本地日期、时间(年、月、日、星期、时,分,秒,纳秒)

      获取对象的方法 获取系统当前时间对象

      API获取对象方法
      LocalDateLocalDate a = LocalDate.now()
      LocalTimeLocalTime a = LocalTime.now()
      LocalDateTimeLocalDateTime a = LocalDateTime.now()

      ZoneId、ZoneDateTime

      ZoneId:时区ID

      ZoneDateTime:带有时区的时间

      常用方法和LocalDate、LocalTime、LocalDateTime相似

       

      Instant

      通过获取instant的对象可以拿到此刻的时间,该事件由两部分组成:从1970年1月1日 0 时起至今的总秒数 和 不足1秒的纳秒数。

      方法名返回值类型说明
      now() 获取当前时间的 Instant对象
      getEpochSecond()long从时间线开始的秒数
      GetNano()int获取上面的纳秒数
      plusxxx 增加xx时间
      minusxxx 减少xx时间
      equals,isBefore,isAfter 判断方法

      Instant精确,可以获得纳秒值,可以做代码的性能分析,或记录用户操作的时间点。

       

      DateTimeFormatter

      格式化器,用于时间的格式化和解析

      常用方法

      方法名返回值类型说明
      ofPattern(时间格式)DateTimeFormatter获取格式化器对象
      format(时间对象)String格式化时间

       

      Duration、Period

      这两个类是用来计算时间间隔的

      Period:计算两个日期对象(LocalDate)日期间隔(年、月、日)

      Period常用方法

      方法名返回值类型说明
      between(LocalDate 开始,LocalDate 结束)Period传入两个日期对象,得到Period对象
      getYears()int计算年份间隔并返回
      getMonths()int计算月份间隔并返回
      getDays()int计算天数间隔并返回

       

      Duration:计算时间对象(LocalTime)间隔(时、分、秒、纳秒)

      支持LocalTime,LocalDateTime,Instant等时间

      方法名返回值说明
      between(开始时间,结束时间)Duration传入两个事件对象,得到Duration对象
      toDays()long计算间隔多少天并返回
      toHours()long计算间隔多少小时并返回
      toMinutes()long计算间隔多少分钟并返回
      toSeconds()long计算间隔多少秒并返回
      toMillis()long计算间隔多少毫秒并返回
      toNanos()long计算间隔多少纳秒并返回

      使用方法和上面一样

       

      Arrays

      是用来操作数组的一个工具类

      常用方法

      方法名返回值类型说明
      toString(类型[] a)String返回数组的内容
      copyOfRange(类型[] a,起始索引,结束索引)int[]拷贝指定范围内的数组
      copyOf(类型[] a,int 新数组长度) 拷贝数组,常用于数组扩容
      setAll(double[] a, IntToDoubleFunction) 把数组中的原数据修改为新数据
      sort(类型[] a) 对数组进行排序,默认升序

      Lambda(JDK8+)

      Lambda表达式,适用于简化匿名内部类代码的写法

      代码格式

      Lambda表达式不能简化所有的匿名内部类,只能简化函数式接口(1.必须是接口 2.接口中只有一个抽象方法)的匿名内部类。

      Lambda表达式的省略规则

      1. 参数的类型可以省略不写

      2. 如果只有一个参数,参数类型可以省略,()也可以省略

      3. 如果表达式中的方法体只有一行代码,大括号可以省略,同时也要省略分号!,如果这行代码是return语句,也必须去掉return不写

      方法引用(JDK8+)

      静态方法引用

      方法引用的标志:“ :: ” 两个冒号

       

      实例方法引用

       

      特定类型方法引用

       

      构造器引用

       

      正则表达式

      正则表达式就是一些特定字符组成的,代表一个规则

      作用:

      1. 用来校验数据格式是否正确,如:电话号码,邮箱地址等

      2. 在一段文本中查找满足要求的内容

      正则表达式的书写规则见官方文档。

       

      异常

      异常就是代表程序出现的问题

      image-20240729181758787

      Error:代表系统级错误(严重问题)

      Exception:异常,代表我们程序出现的问题

       

      自定义异常

      java无法为所有的问题都提供异常类来代表,若自己遇到某些问题,需要通过异常来代表,就需要自己定义异常类

      自定义运行时异常方法

      自定义编译时异常方法

       

      异常的处理

      在开发中常用的处理异常方法

       

      集合框架

      在Java中整体来看集合体系结构主要分 Collection(单列集合):每个元素只包含一个值 Map(双列集合):每个元素包含两个值(键值对)

      Collection集合体系

      Collection是一个泛型接口

      image-20240729213142579

      List系列集合的特点:添加的元素是有序的,可重复的,有索引的

      set系列集合的特点:添加的元素是无序的,不重复的,无索引的

       

      Collection的常用方法

      Collection是单列集合的祖宗,他的方法单列集合都会继承

      方法名返回值类型说明
      add(E e)boolean向集合中添加元素
      clear()void清空集合
      isEmpty()boolean判断集合是否为空
      size()int获取集合的大小
      contains(Object obj)boolean判断集合中是否包含某个元素
      remove(E e)boolean删除某个元素,或有多个,默认删除第一个
      toArray()Object[]把集合转换成数组

       

      Collection的遍历方式

       

       

      案例:遍历集合中的自定义对象

      需求:展示多部电影的信息

       

      List系列集合

      特点:有序,可重复,有索引

      特有方法 由于List集合是支持索引的,所以该集合有很多索引相关的方法,也继承了Collection的方法,这些方法List系列集合都是支持的。

      方法返回值说明
      add(int index, E element)void在集合的指定位置插入元素
      remove(int index)E删除指定索引处的元素,返回被删除的元素
      set(int index,E element)E修改指定索引处的元素,返回被修改的元素
      get(int index)E返回指定索引处的元素

      遍历方法

       

      ArrayList集合的底层原理

      原理

      1. ArrayList是基于数组实现的

      2. 利用无参构造器创建的集合,会在底层创建一个默认长度为0的空数组

      3. 在添加第一个元素时,底层会创建一个新的长度为10的数组

      4. 数组存满时会扩容1.5倍

      5. 若一次添加多数据,1.5倍长度放不下时,新创建数组的长度以实际的元素个数为准。

       

      特点

      1. 根据索引查询数据速度快:根据地址值+索引定位,查询任意数据耗时相同

      2. 删除效率低

      3. 添加效率极低

       

      场景

      1. 适合根据索引查询数据或数据量不是很大时,查询效率高

      2. 不适合数据量太大同时需要频繁进行增删操作的场景

       

      LinkedList集合的底层原理

      原理

      1. LinkedList是基于双链表实现的

      特点

      1. 查询速度慢,查询那个数据都是从头结点开始

      2. 增删相对较快 ,对首尾元素增删改查的速度极快

      首尾元素操作的特有方法

      方法名返回值说明
      addFirst(E e)void在该列表的靠头插入元素
      addLast(E e)void在该列表的末尾插入元素
      getFirst()E返回列表中的第一个元素
      getLast()E返回列表中的最后一个元素
      removeFirst()E删除列表中的第一个元素并返回
      removeLast()E删除列表中的最后一个元素并返回

      场景

      可以用来设计队列,先进先出,后进后出(两端开口) 开发叫号系统,排队系统。

      可以用来设计栈:后进先出,先进后出(一端开口)

       

      Set系列集合

      特点

       

      常见实现类

      HashSet:无序,不重复,无索引 LinkedHashSet:有序,不重复,无索引 TreeSet:排序(默认升序),不重复,无索引

      Set集合的常用方法,基本上就是Collection提供的

       

      HashSet底层原理

      Hash:哈希值-就是一个int类型的数值,在Java中每个对象都有一个哈希值 在Java中,可以使用Object类的hashCode方法获得对象的哈希值 哈希表是一种增删改查数据性能较好的数据结构。

       

      LinkedHashSet(HashSet的子类)底层原理

       

      TreeSet底层原理

      注意:TreeSet规则在存储自定义类型的对象时,必须指定排序规则,否则就会报错

      自定义规则的方式

      1. 让自定义类实现Comparable接口,重写里面的compareTo方法来指定比较规则

      2. 通过调用TreeSet集合的有参构造器,可以设置Comparator对象(比较器对象,指定比较规则)

       

      集合并发修改异常问题

      比如:使用迭代器在遍历集合时,又同时在删除集合中的数据,程序就会出现并发修改异常错误

      注意:增强for循环就是迭代器的简化写法,其在遍历删除数据时,会出现并发修改异常问题,并且是无法解决的。

      例如有一组存有人名的集合数据,找到全部名字带张的并删除

      避免在遍历集合删除数据时发生BUG

      1. 使用迭代器的remove方法

      2. 使用for循环,倒着遍历并删除,或者正向遍历,删除后循环计数器-1

       

      可变参数

      是一种特殊的形参,定义在方法、构造器的形参列表里,格式:数据类型...参数名称

      可变参数的特点和好处 特点:可以不传入数据给它,可以传一个或多个数据,也可以传一个数组 好处:用来灵活的接收数据

      注意: 一个形参列表中只能有一个可变参数 可变参数必须在形参列表的最后一个

       

      Collections工具类

      Collections常用的静态方法

      方法名说明
      public static <T> boolean addAll(Collection<? super T> c,T...elements)给集合批量添加元素
      public static void shuffle(List<?> list)打乱List集合的元素顺序
      public static <T> sort(List<?> list)对List集合中的元素进行升序排序
      public static <T> sort(List<?> list,Comparator<? super T> c)对List集合中的元素按照比较器指定的规则进行排序

       

      Map集合体系

      概述

      image-20240730195952796

      特点 HashMap(由键决定特点):无需,不重复,无索引(用的最多) LinkedHashMap(由键决定特点):有序,不重复,无索引 TreeMap(由键决定特点):按照键的大小升序排序,不重复,无索引

      常用方法
      方法返回值类型说明
      size()int获取集合大小
      clearvoid清空集合
      isEmpty()boolean判断集合是否为空
      get(Object key)v根据键获取对应的值
      remove(Object key)v根据键删除对应的值
      containsKey(Object key)boolean判断是否包含某个键
      containsValue(Object value)boolean判断是否包含某个值
      keySet()set<k>获取Map集合的全部键
      valuescollection<v>获取Map集合的全部值
      putAll 将一个集合中的数据倒入到另一个集合

       

      遍历方式
      1. 键找值 先获取map集合的所有键,再通过遍历键查找值

         

      2. 键值对 把键值对,看成一个整体进行遍历,(代码难度大)

      3. Lambda表达式 这种方式非常简单

         

      HashMap

      HashMap的底层原理和HashSet的底层原理是一样的,都是基于哈希表实现的

       

      LinkedHashMap

      LinkedHashMap底层数据结构是基于哈希表实现的,每个键值对元素又多了一个双链表的机制记录元素的顺序。 LinkedHashSet集合的底层原理就是LinkedHashMap。

      TreeMap

      TreeMap的底层原理和TreeSet一样,利用了红黑树排序。 如果TreeMap存储的自定义类型可以自定义排序规则。 1.让类实现Comparable接口,重写comparTo比较规则。 2.TreeMap集合有一个有参构造器,支持创建Comparator比较器对象来指定规则。

       

      集合嵌套

      使用场景:记录省份及其城市名。

      例如:河北省=石家庄市,沧州市,... 就可以使用集合嵌套的方式,省份名称作为键,城市集合作为值。

       

      Stream流

      认识c Stream是JDK8开始新增的一套API,可以用于操作集合或数组的数据。

      Stream的优势 Stream流大量结合了lambda的语法编程,提供了一些更强大,更简单的方式操作集合或者数组中的数据,更简洁,代码可读性更好。

      Stream流的用法

      1. 获取集合/数组的Stream流

        • 集合

        Collection提供的方法说明
        stream()获取当前集合的stream流

         

        • 数组

        Arrays提供的方法说明
        stream(T[] arr)获取当前数组的stream流
        Stream类提供的方法说明
        of(T...VALUES)获取当前接受数据的stream流

         

         

      2. 使用Stream流的常用方法,支持链式编程

        方法名返回值说明
        filter(Predicate<? super T> predicate)Stream<T>对流中的数据进行筛选
        sorted()Stream<T>对元素进行升序排序
        sorted(Comparator <? super T> comparator)Stream<T>按照规则进行排序
        limit(long maxSize)Stream<T>获取前几个元素
        skip(long n)Stream<T>跳过前几个元素
        distinct()Stream<T>去除流中的重复元素
        map(Function<? super T,? extends R> mapper)Stream<R>对元素进行加工并返回新的数据流
        concat(Stream a,Stream b)Stream<T>合并ab数据流

         

      3. 使用Stream流终结方法

        方法名说明
        forEach(Consumer)对流云算完后的元素进行遍历
        const()统计流运算完成后的元素个数
        max()获取流运算完成后的最大元素
        min()获取流运算完成后的最大元素

         

      4. 收集stream流:把stream流操作后的结果转到集合或数组中返回

        stream流的常用终结方法说明
        collect()把流处理后的结果收集到一个集合中
        toArray()把流处理后的结果收集到一个数组中
        Collectors工具类提供的收集方法说明
        toList()把元素收集到List集合中
        toSet()把元素收集到Set集合中
        toMap()把元素收集到Map集合中

       

      文件操作

      File

      File是java.io包下的类,File类的对象,用于代表当前操作系统的文件 File可以获取文件信息(大小,文件名等),判断文件类型,创建删除文件或文件夹等功能 File只能对文件本身进行操作,不能读写文件内部存储的数据

       

      方法递归

      认识方法递归

      递归的形式

      递归使用时,需要控制终止,否则会出现递归死循环,导致栈内存溢出的错误

      方法递归原理思想

      递归的三要素总结

      案例:计算N的阶乘

      案例:猴子吃桃问题

      案例:文件搜索

      需求:搜索qq音乐的启动文件,QQMusic.exe

      分析:

      1. 找到盘符下的所有一级文件对象

      2. 遍历所有文件对象,判断是否是文件

      3. 如果是文件,判断是否是想要的启动程序

      4. 如果是文件夹则进入文件夹继续查找

      案例:删除非空文件夹

       

      IO流

      IO流是用于读写数据的,可以读写文件数据,也可以读写网络中的数据

      IO流在java.io中

      IO流总体分为四大流,这四大流都是抽象类

      这四类对应的实现类为

      FileInputStream,FileOutputStream,FileReader,FileWriter

       

      文件字节输入流——FileInputStream

      以内存为基准,可以把磁盘中的文件的数据以字节的形式读入到内存

      构造器说明
      FileInputStream(File file)创建字节输入流
      FileInputStream(String pathname)创建字节输入流
      方法名返回值说明
      read()int读取一个字节返回,若没有数据,返回-1
      read(byte[] b)int每次用一个字节数组去读取数据,返回字节数组读取了多少个字节,没有发现数据返回-1

       

      文件字节输出流——FileOutputStream

      以内存为基准,可以把磁盘中的文件的数据以字节的形式读入到内存

      构造器说明
      FileOutputStream(File file)创建字节输出流与源文件对象连通
      FileOutputStream(String filepath)创建字节输出流与源文件对象连通
      FileOutputStream(File file,boolean append)创建字节输出流与源文件对象连通,可追加数据
      FileOutputStream(String filepath,boolean append)创建字节输出流与源文件对象连通,可追加数据
      方法说明
      write(int a)写一个字节
      write(byte[] buffer)写一个字节数组
      write(byte[] buffer,int begin,int last)写一个字节数组的一部分
      close()关闭流

       

      资源释放方式

      文件字符输入流——FileReader

      构造器说明
      FileReader(File file)创建字符输入流管道
      FileReader(String pathname)创建字符输入流管道
      方法说明
      read()每次读取一个字符
      read(char[] buffer)每次读取多个字符

       

      文件字符输出流——FileWriter

      构造器说明
      FileWriter(File file)创建字节输出流与源文件对象连通
      FileWriter(String filepath)创建字节输出流与源文件对象连通
      FileWriter(File file,boolean append)创建字节输出流与源文件对象连通,可追加数据
      FileWriter(String filepath,boolean append)创建字节输出流与源文件对象连通,可追加数据
      方法说明
      write(int a)写一个字符
      write(String str)写一个字符串
      write(String str,int begin,int last)写一个字符串的一部分
      write(byte[] buffer)写一个字符数组
      write(byte[] buffer,int begin,int last)写一个字符数组的一部分
      close()关闭流

      注意! 字符输出流写出数据后,必须刷新或关闭流,写出的数据才能生效!

      刷新流(flash),关闭流(close)

      字节流适合一切文件数据的拷贝;不适合读取中文字符输出 字符流适合做文本文件的读写等操作

      IO流--缓冲流 缓冲流的作用:包装原始流,提高原始流的读写性能,自带默认大小为8K的

      IO流--转换流 不同的编码在读取时,会出现乱码问题

      IO流--打印流 作用:打印流可以实现更加方便高效地打印数据。

      IO流--数据流 可以把数据和其数据类型一并写出

      构造器说明
      DataOutputStream(OutputStream o)创建新的字节数据输出流
      DataInputStream(InputStream o)创建新的字节数据输入流
      方法说明
      writeByte()/readByte()将byte数据写入(读取)输出流
      writeInt()/readInt()将int数据写入(读取)输出流
      writeDouble()/readDouble()将double数据写入(读取)输出流
      writeUTF()/readUTF()将字符串数据以UTF-8编码成字节写入(读取)输出流
      write()/read()支持写(读取)字节数据

       

      IO流--序列化流

      可以对对象进行序列化:把java对象写入到文件中 也可以对对象进行反序列化:把文件中的java对象读取出来

      对象字节输出流

      构造器说明
      ObjectOutputStream(OutputStream out)创建对象字节输出流,包装基础的字节输出流
      方法说明
      writeObject(Object o)把对象写入文件

      对象字节输入流

      构造器方法
      ObjecInputStream(InputStream in)创建字节输入流对象,
      方法说明
      readObject(Object o)把文件中的对象读取出来

      需要序列化的对象,需要实现一个Serializable接口

      如果不想让类中的某个遍历参与序列化(如密码等),可以在其前面加一个transient修饰符

       

      IO框架

      框架:为了解决一类问题,编写的一套类/接口等。 好处:在框架的基础上开发,可以得到优秀的软件架构,提高开发效率

      IO框架:封装了Java提供的对文件,数据操作的代码,对外提供了更简单的方式对文件进行操作

       

      特殊文件

      属性文件--Properties

      特点: 存取格式:key =value key是不能重复的 后缀一般是为:Properties

      作用: 用来存储键值对数据

      读取属性文件数据 使用Java提供的Properties 它是一个Map集合,但是一般不当作集合使用

      构造器说明
      Properties()用于构建Properties集合对象,为空容器
      方法返回值说明
      load(InputStream i)void通过字节输入流读取文件里的键值对数据
      load(Reader r)void通过字符输入流读取文件里的键值对数据
      getProperty(String key)String根据键获取值
      stringPropertyNames()Set<String>获取全部的键集合

      存储数据到属性文件

      方法返回值说明
      setProperty(String key,String value)Object保存键值对数据到Properties对象中
      store(OutputStream os,String comments)void把键值对数据通过字节输出流写入到属性文件
      store(Write w,String comments)void把键值对数据通过字符输出流写入到属性文件

      XML文件--可扩展标记语言

      本质是一种数据的格式,可以用来存储复杂的数据结构和数据关系,例如:可以存储一个用户的多个数据:用户名,密码,性别,年龄等

      XML标签的特点

      读取文件数据

      java有提供了第三方框架解析XML文件,例如:Dom4j等

      写入数据结构

      dom4j 可以使用拼接方式将数据写入到XML文件

       

      日志技术

      image-20240806183825257

      Logback Home (qos.ch)

      日志级别说明
      trace跟踪,指明程序运行的轨迹(很少用)
      debug调试,实际用应用时一般作为最低级别
      info输出重要的运行信息
      warn警告信息,记录可能会发生的问题
      error错误信息,记录发生的错误

       

      多线程

      多线程是指从软硬件上实现的多条执行流程技术(多条流程由CPU负责调度执行)

      创建多线程

      Java通过java.lang.Thread类的对象来代表线程

      1. 将类声明为Thread的子类,并重写run方法 调用线程对象的start()方法启动线程

        优点:编码简单 缺点:不能再继承其他类,比例与扩展

        注意: 启动时,必须调用strat方法,不能调用run方法 不要把主线程放在在子线程之前启动。

      2. 声明一个实现Runnable接口的类,然后实现run方法

        优点:任务只实现了接口,还可以继承其他类,扩展性更强

        另一种方法:匿名内部类形式

         

      3. 利用Callable接口,FutureTask类来实现

        若要run执行完后,有一些数据需要返回,前面两种方式都无法满足这个需求,就需要用到这种方式

        1. 创建任务对象,定义一个类,实现callable方法,重写call方法,封装业务逻辑代码和返回的数据

        2. 创建callable对象

        3. 将callable对象交给未来任务对象FultureTask

        4. 把未来任务对象交给Thread对象

        5. 调用Thread对象的start方法启动线程

        6. 线程执行完毕后通过FutureTask对象的get方法区获取线程任务的执行结果

        优点:线程任务类只实现了接口,可以继续继承类和实现接口,扩展性更好,可以在线程执行完毕后获取线程执行的结果。

       

      Thread常用方法

      方法说明
      run()线程的任务方法
      start()启动线程0
      getName()获取当前线程的名称,默认名称:Thread-索引
      setName(String name)为线程设置名称
      currentThread()获取当前执行的线程对象
      sleep(long time)让当前执行的线程休眠xx毫秒后继续执行
      join()让调用当前这个方法的线程先执行完
      构造器说明
      Thread(String name)可为线程指定名称
      Thread(Runnable tar)封装Runnable对象为线程对象
      Thread(Runnable tar,String name)封装Runnable对象为线程对象,为线程指定名称

       

      线程安全

      多个线程,在同时操作一个共享资源时,可能会出现业务安全问题。

      模拟线程安全问题

       

      线程同步

      为了解决线程安全的问题,需要使用线程同步解决此问题。 让多个资源实现先后依次访问共享资源

      常见方案 加锁:只允许一个线程加锁,线程加锁后才能进入访问资源,访问完毕后自动解锁,然后其他进程才能继续加锁来进行访问。

      线程通信

      当多个线程共同操作共享的资源时,线程通过某种方式告知自己的状态,以便相互协调,并避免无效的资源争夺

       

      线程池

      是一个可以复用线程的技术 当用户请求次数过多时,会创建出大量的新线程,占用CPU内存资源,这样会严重影响系统的性能

      创建线程池

      方法1:线程池接口:ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象

      参数解释

      参数说明
      corePoolSize线程池的核心线程的数量
      maximumPoolSize线程池的最大线程数量
      keepAliveTime临时线程的存活时间
      unit临时线程存活时间的单位
      workQueue线程池的任务队列
      threadFactory指定线程池的线程工厂
      handler指定线程池的任务拒绝策略,线程满了,任务队列也满了,新任务再来了该如何处理

       

      方法2:Executors工具类实现线程池

      方法名说明
      newFixedThreadPool(int)创建固定线程数量的线程池,如果某个线程因为异常而结束,线程池中会补充一个新的线程来替换它。
      newSinglethreadExecutor()创建只有一个线程的线程池对象,如果该线程出现异常而结束,线程池中会补充一个新的线程来替换它。
      newCachedThreadPool()线程随任务增加而增加,如果线程任务执行完毕空闲60秒则会被回收。
      newSchediledThreadPool(int)创建一个线程池,可以实现给定的延迟后执行任务或定期执行任务。

      这些方法都是通过线程池的实现类ThreadPoolExecutor创建的线程池对象 Executors在大型并发系统环境中如果不注意,可能会出现系统风险问题

       

      处理Runnable,Callable任务

      ExecutorService的常用方法

      方法名返回值说明
      execute(Runnable cmd)void执行Runnable任务
      submit()Future<T>执行Callable任务,返回未来任务对象,用于获取线程返回的结果
      shutdown()void等待全部任务执行完成后,再关闭线程池
      shutdownNowList<Runnable>立即关闭线程池,停止正在执行的任务,返回未执行的任务

       

      并发,并行

      正在运行的程序/软件就是一个独立的进程。 线程是属于进程的,一个进程可以同时运行多个线程 进程中的多个线程是并发和并行执行的。

      什么是并发? 进程中的线程是由CPU负责调度执行的,但CPU能同时处理线程的数量有限,为了保证全部线程都能往前执行,CPU会轮询为系统的每个线程服务,由于CPU切换的速度很快,给我们的感觉这些线程在同时执行,这就是并发。

      什么是并行? 在同一时刻,同时有多个线程在被CPU调度执行

      并发和并行是同时进行的

       

      线程的生命周期

      Java线程有6种 状态

      image-20240804000708021

       

      乐观锁

      一开始不上锁,等要出现线程安全问题的时候才开始控制。性能较好,线程安全。

      Java内置的,AtomicInteger(Atomicxxx)实现乐观锁

       

      网络通信

      概述

      网络通信三要素

      IP地址 设备在网络中的地址,是唯一的标识

      端口号 应用程序在设备中的唯一标识

      协议 连接和数据在网络中传输的规则

       

      InetAddress

      Java提供的一个类,代表IP地址。 InetAddress常用方法

      名称返回值类型说明
      getLocalHost()InetAddress获取本机IP,返回一个InetAddress对象
      getByName(String host)InetAddress根据IP地址或域名,返回一个InetAddress对象
      getHostName()String获取IP地址对象对应的主机名
      getHostAddress()String获取当前IP地址对象对应的IP地址信息
      isReachable(int timeout)boolean在指定的毫秒内,判断主机与该IP地址对应的主机是否能够连通

       

      端口

      端口:标记正在计算机设备上运行的应用程序

      端口分类

      自己开发的程序一般选择注册端口号,且一个设备中不能出现两个程序的端口号相同的情况

      协议

      网络上通信的设备,事先规定的连接规则,以及传输数据的规则,被称为网络通信协议

      OSI网络参考模型:OSI网络参考模型

      image-20240807134712688

      TCP/IP网络模型:事实上的网络标准

       

      UDP通信

      特点:无连接,不可靠通信

      在Java中提供了一个java.net.DatagramSocket类实现UDP通信

      构造器说明
      DatagramSocket()创建客户端socket对象,系统会随机分配一个端口
      DatagramSocket(int port)创建客户端socket对象,指定一个端口
      方法说明
      send(DatagramPacket dp)发送数据包
      receive(DatagramPacket p)使用数据包接收数据

      DatagramPacket:创建数据包

      构造器说明
      DatagramPacket(byte[] b, int length, InetAddress address, int port)创建发出去的数据包对象
      DatagramPacket(byte[] b, int length)创建用来接收数据的数据包

      客户端程序

      服务端程序

       

      TCP通信

      特点:面向连接的可靠通信 通信双方先采用三次握手的方式建立可靠连接,实现端到端的通信,保证数据能够成功传输

       

      客户端开发

      在Java中提供了java.net.Socket类实现TCP通信

      构造器说明
      Socket(String host int port)根据指定的IP和端口号请求与服务端建立连接,成功后,就获得客户端socket
      方法返回值说明
      getOutputStream()OutputStream获得字节输出流对象--发送数据
      getInputStream()InputStream获取字节输入流对象--接收数据

       

      服务端开发

      通过java.net.ServerSocket类来实现

      构造器说明
      ServerSocket(int port)为服务端程序注册端口
      方法返回值说明
      accept()Socket阻塞等待客户端的请求连接,一旦连接成功,就会返回服务端的Socket对象

       

      上面的客户端与服务器程序中,服务器只能接收一个客户端的数据,无法与多个客户端同时通信 让服务器可与多个客户端同时通信的方法——多线程 主线程:负责不断地接收新的客户端连接

       

      案例:群聊 需求,一个人发消息,群聊中的其他人可以接收到这个消息

       

      BS架构开发

      BS架构只需要开发服务端

      HTTP协议规定的数据格式

      image-20240808121905325

      面对访问量较大的时候,每次请求都建立一个新的线程,容易让系统崩溃,可以用线程池解决这一问题,在高并发下,也不会让系统瘫痪

       

      Java高级技术

      单元测试

      针对最小的功能单元进行测试,编辑测试代码对其进行正确性测试 之前要测试某一方法,需要在main方法中编写测试代码,不灵活,不方便

      Junit测试框架

      在IDEA中集成了该框架 优点: 可以灵活的编写代码,对某个方法进行测试,也就可以一键完成对全部方法的自动化测试 不需要自己去分析测试结果,会自动生成测试报告

      使用步骤:

      1. 将Junit框架导入到项目

      2. 为需要测试的业务类定义对应的测试类,并为每个业务方法编写对应的测试方法(必须公共,无参,无返回值)

      3. 测试方法上必须声明@Test注解,然后在测试方法中,编写代码调用被测试的业务方法进行测试。

      4. 开始测试:选中测试方法,右键选择Junit印象,结果为绿色代表成功,红色代表失败。

      断言机制:通过预测结果和实际运行结果对比,判断程序中是否存在bug

       

      Junit框架常见注解
      注解说明
      @Test测试类中的方法必须用这个注解修饰才能成为测试方法,才能启动执行
      @Before用来修饰一个实例方法,该方法会在每一个测试方法执行前执行一次
      @After用来修饰一个实例方法,该方法会在每一个测试方法执行后执行一次
      @BeforeClass用来修饰一个静态方法,该方法会在所有测试方法之前只执行一次
      @AfterClass用来修饰一个静态方法,该方法会在所有测试方法之后只执行一次

      在测试方法之前执行的方法常用于初始化资源 在测试方法之后执行的方法常用于释放资源

       

       

      本文档到此结束,感谢!!